package com.purchase.ml.service.report.impl;

import com.purchase.ml.bean.page.Page;
import com.purchase.ml.bean.req.report.*;
import com.purchase.ml.bean.res.report.*;
import com.purchase.ml.bean.res.report.vo.ReportDealerSalesDetailVo;
import com.purchase.ml.bean.res.report.vo.ReportDealerSalesVo;
import com.purchase.ml.bean.res.report.vo.ReportOnlineVo;
import com.purchase.ml.bean.res.report.vo.ReportRegoinCollectVo;
import com.purchase.ml.bean.vo.order.OrderCollectAmtVo;
import com.purchase.ml.config.RedisConfiguration;
import com.purchase.ml.consts.CommonConsts;
import com.purchase.ml.entity.acc.SysUser;
import com.purchase.ml.mapper.dealer.SysDealerMapper;
import com.purchase.ml.mapper.order.SysDealerCollectMapper;
import com.purchase.ml.mapper.order.SysOrderMapper;
import com.purchase.ml.security.JwtUtil;
import com.purchase.ml.service.dealer.SysDealerService;
import com.purchase.ml.service.report.ReportService;
import com.purchase.ml.service.report.asyn.ReportServiceAsyn;
import com.purchase.ml.utils.DataConversionUtils;
import com.purchase.ml.utils.Ipay88ChannelUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Future;
import java.util.stream.Collectors;

/**
 * Created by kyyang on 2021/3/4 23:12
 */
@Slf4j
@Service
@Component
public class ReportServiceImpl  implements ReportService {

    @Autowired
    private SysDealerService sysDealerService;

    @Autowired
    private SysDealerCollectMapper sysDealerCollectMapper;

    @Autowired
    private SysOrderMapper sysOrderMapper;

    @Autowired
    private SysDealerMapper sysDealerMapper;

    @Autowired
    private ReportServiceAsyn reportServiceAsyn;

//    @Cacheable(value = RedisConfiguration.REDIS_DATA_I_H_CACHE)
    @Override
    public ReportAdminRes queryAdminReport(ReportAdminReq req) throws Exception {
        ReportAdminRes reportAdminRes = new ReportAdminRes();
        //1 、查出总订单数、总销售额 、总利润
        Future<ReportAdminRes> f1 = reportServiceAsyn.queryAdminReportToTalPosAndAmtAndProfit(req,CommonConsts.ROLETYPE_MASTER);
        //2 、查出利润明细
        Future<List<OrderCollectAmtVo>> f2 = reportServiceAsyn.queryAdminReportProfitDetail(req,CommonConsts.ROLETYPE_MASTER);
        //3 、查出区域汇总
        Future<List<ReportRegoinCollectVo>> f3 = reportServiceAsyn.queryAdminReportRegoinCollect(req,CommonConsts.ROLETYPE_MASTER);
        //4 、销售额前10主 经销商
        Future<List<ReportDealerSalesDetailVo>> f4 = reportServiceAsyn.queryAdminReportMasterDealerLimit(req,CommonConsts.ROLETYPE_MASTER,10);

        if(f1!=null){
            ReportAdminRes reportAdminRes1 = f1.get();
            if(reportAdminRes1!=null){
                reportAdminRes.setTotalPOs(reportAdminRes1.getTotalPOs());
                reportAdminRes.setTotalSales(reportAdminRes1.getTotalSales());
                reportAdminRes.setTotalProfit(reportAdminRes1.getTotalProfit());
            }
        }
        if(f2!=null){
            List<OrderCollectAmtVo> orderCollectProfitVos = f2.get();
            if(orderCollectProfitVos!=null&&orderCollectProfitVos.size()>0){
                Map<String, Double> map = orderCollectProfitVos.stream().collect(Collectors.toMap(OrderCollectAmtVo::getDataDate, e -> e.getAmt().doubleValue()));
                reportAdminRes.setProfitDetail(DataConversionUtils.getCurDateMonthDataInit(req.getStartTime(),req.getEndTime(),map));
            }
        }
        if(f3!=null){
            List<ReportRegoinCollectVo> reportRegoinCollectVos = f3.get();
            if(reportRegoinCollectVos!=null&&reportRegoinCollectVos.size()>0){
                for(ReportRegoinCollectVo r:reportRegoinCollectVos){
                    String regionName = r.getRegionName();
                    List<OrderCollectAmtVo> list = sysDealerCollectMapper.selectTotalAmtDetailByRegion(regionName,req.getStartTime(),req.getEndTime(),CommonConsts.ROLETYPE_MASTER);
                    if(list!=null&&list.size()>0){
                        Map<String, Double> map = list.stream().collect(Collectors.toMap(OrderCollectAmtVo::getDataDate, e -> e.getAmt().doubleValue()));
                        r.setDetails(DataConversionUtils.getCurDateMonthDataInit(req.getStartTime(),req.getEndTime(),map));
                    }
                }
                reportAdminRes.setRegoinCollect(reportRegoinCollectVos);
            }
        }
        if(f4!=null){
            List<ReportDealerSalesDetailVo> reportDealerSalesDetailVos = f4.get();
            if(reportDealerSalesDetailVos!=null &&reportDealerSalesDetailVos.size()>0){
                for(ReportDealerSalesDetailVo r:reportDealerSalesDetailVos){
                    Long dealerId = r.getDealerId();
                    List<OrderCollectAmtVo> list = sysDealerCollectMapper.selectTotalAmtDetailByDealer(dealerId,req.getStartTime(),req.getEndTime(),CommonConsts.ROLETYPE_MASTER);
                    if(list!=null&&list.size()>0){
                        Map<String, Double> map = list.stream().collect(Collectors.toMap(OrderCollectAmtVo::getDataDate, e -> e.getAmt().doubleValue()));
                        r.setDetails(DataConversionUtils.getCurDateMonthDataInit(req.getStartTime(),req.getEndTime(),map));
                    }
                }

                reportAdminRes.setMasterDealerSales(reportDealerSalesDetailVos);
            }
        }


        return reportAdminRes;
    }

    @Cacheable(value = RedisConfiguration.REDIS_DATA_I_H_CACHE)
    @Override
    public Page<ReportDealerSalesVo> queryMasterDealerSalesPageReport(ReportDealerReq reportDealerReq) {
        Page<ReportDealerSalesVo> result = new Page<ReportDealerSalesVo>(reportDealerReq.getPageIndex(),reportDealerReq.getPageNum());
        SysUser currentUser = JwtUtil.getCurrentUser();
        int dealer_type = CommonConsts.ROLETYPE_MASTER;
        if(currentUser.getRoleType()==CommonConsts.ROLETYPE_MASTER){
             dealer_type = CommonConsts.ROLETYPE_DEALER;
        }

        int count = sysDealerCollectMapper.selectyMasterDealerSalesPageReportCount(dealer_type,reportDealerReq.getDealerId(),reportDealerReq.getStartTime(),reportDealerReq.getEndTime());
        List<ReportDealerSalesVo> records = sysDealerCollectMapper.selectyMasterDealerSalesPageReport(dealer_type,reportDealerReq.getDealerId(),reportDealerReq.getStartTime(),reportDealerReq.getEndTime(),reportDealerReq.getStart(),reportDealerReq.getEnd());
        result.setTotal(count);
        result.setRecords(records);
        return result;
    }

//    @Cacheable(value = RedisConfiguration.REDIS_DATA_I_H_CACHE)
    @Override
    public Map<String, Object> queryOnlineTransactionReport(ReportOnlineTransactionReq req) throws Exception{

        Map<String,Object> map = new HashMap<>();

        BigDecimal totalAmt = BigDecimal.ZERO;
        List<ReportOnlineTransactionRes> list = new ArrayList<>();
        int count = 0;
        //查询出日期范围内总金额
        Future<ReportOnlineVo> f1 = reportServiceAsyn.queryOnlineTransactionReportToTalAmt(req,CommonConsts.ROLETYPE_DEALER);

        //分页查询该日期范围内明细
        Future<List<ReportOnlineTransactionRes>> f2 = reportServiceAsyn.queryOnlineTransactionReportDetail(req,CommonConsts.ROLETYPE_DEALER);
        if(f1!=null){
            ReportOnlineVo reportOnlineVo = f1.get();
            totalAmt = reportOnlineVo.getTotalAmt();
            count = reportOnlineVo.getTotalRecords();
        }
        if(f2!=null){
            list = f2.get();
        }
        //设置渠道
        for(ReportOnlineTransactionRes res : list){
            res.setChannel(Ipay88ChannelUtils.getCategoryBuyPaymentId(res.getChannel()));
        }
        Page<ReportOnlineTransactionRes> reportOnlineTransactionResPage = new Page<>(req.getPageIndex(),req.getPageNum());
        reportOnlineTransactionResPage.setTotal(count);
        reportOnlineTransactionResPage.setRecords(list);
        map.put("totalSales",totalAmt);
        map.put("tradDetail",reportOnlineTransactionResPage);
        return map;
    }

//    @Cacheable(value = RedisConfiguration.REDIS_DATA_I_H_CACHE)
    @Override
    public Map<String, Object> queryMasterDealerSalesReport(ReportMasterDearSaleReq req) throws Exception{

        Map<String,Object> map = new HashMap<>();

        BigDecimal totalAmt = BigDecimal.ZERO;
        List<ReportMasterDearSaleRes> list = new ArrayList<>();

        int roleType = CommonConsts.ROLETYPE_MASTER;
        if(req.getDealerId()!=null){
            roleType = CommonConsts.ROLETYPE_DEALER;
        }


        int count = 0;
        //查询出日期范围内总金额
        Future<ReportOnlineVo> f1 = reportServiceAsyn.querMasterDealerSalesToTalAmt(req,roleType);

        //分页查询该日期范围内明细
        Future<List<ReportMasterDearSaleRes>> f2 = reportServiceAsyn.queryMasterDealerSalesDetail(req,roleType);

        if(f1!=null){
            ReportOnlineVo reportOnlineVo = f1.get();
            totalAmt = reportOnlineVo.getTotalAmt();
            count = reportOnlineVo.getTotalRecords();
        }
        if(f2!=null){
            list = f2.get();
        }
        Page<ReportMasterDearSaleRes> reportOnlineTransactionResPage = new Page<>(req.getPageIndex(),req.getPageNum());
        reportOnlineTransactionResPage.setTotal(count);
        reportOnlineTransactionResPage.setRecords(list);
        map.put("totalSales",totalAmt);
        map.put("tradDetail",reportOnlineTransactionResPage);
        return map;
    }

//    @Cacheable(value = RedisConfiguration.REDIS_DATA_I_H_CACHE)
    @Override
    public Map<String, Object> queryProductSalesReport(ReportProductSaleReq req) throws Exception{
        Map<String,Object> map = new HashMap<>();
        BigDecimal totalAmt = BigDecimal.ZERO;
        List<ReportProductSaleRes> list = new ArrayList<>();
        int roleType = CommonConsts.ROLETYPE_MASTER;

        int count = 0;
        //查询出日期范围内总金额
        Future<ReportOnlineVo> f1 = reportServiceAsyn.queryProductSalesReportToTalAmt(req,roleType);

        //分页查询该日期范围内明细
        Future<List<ReportProductSaleRes>> f2 = reportServiceAsyn.queryProductSalesReportDetail(req,roleType);

        if(f1!=null){
            ReportOnlineVo reportOnlineVo = f1.get();
            totalAmt = reportOnlineVo.getTotalAmt();
            count = reportOnlineVo.getTotalRecords();
        }
        if(f2!=null){
            list = f2.get();
        }
        Page<ReportProductSaleRes> reportOnlineTransactionResPage = new Page<>(req.getPageIndex(),req.getPageNum());
        reportOnlineTransactionResPage.setTotal(count);
        reportOnlineTransactionResPage.setRecords(list);
        map.put("totalSales",totalAmt);
        map.put("tradDetail",reportOnlineTransactionResPage);
        return map;
    }


//    @Cacheable(value = RedisConfiguration.REDIS_DATA_I_H_CACHE)
    @Override
    public ReportMasterDealerRes queryMasterDealerReport(ReportAdminReq req) throws Exception{
        ReportMasterDealerRes reportMasterDealerRes = new ReportMasterDealerRes();
        //1 、查出总订单数、总销售额 、总利润
        Future<ReportAdminRes> f1 = reportServiceAsyn.queryAdminReportToTalPosAndAmtAndProfit(req,CommonConsts.ROLETYPE_DEALER);
       //2、查出前10 经销商
        Future<List<ReportDealerSalesDetailVo>> f2 = reportServiceAsyn.queryAdminReportMasterDealerLimit(req,CommonConsts.ROLETYPE_DEALER,10);

        if(f1!=null){
            ReportAdminRes res = f1.get();
            if(res!=null){
                reportMasterDealerRes.setTotalPOs(res.getTotalPOs());
                reportMasterDealerRes.setTotalSales(res.getTotalSales());
                reportMasterDealerRes.setTotalProfit(res.getTotalProfit());
            }
        }
        if(f2!=null){
            List<ReportDealerSalesDetailVo> reportDealerSalesDetailVos = f2.get();
            if(reportDealerSalesDetailVos!=null &&reportDealerSalesDetailVos.size()>0){
                for(ReportDealerSalesDetailVo r:reportDealerSalesDetailVos){
                    Long dealerId = r.getDealerId();
                    List<OrderCollectAmtVo> list = sysDealerCollectMapper.selectTotalAmtDetailByDealer(dealerId,req.getStartTime(),req.getEndTime(),CommonConsts.ROLETYPE_DEALER);
                    if(list!=null&&list.size()>0){
                        Map<String, Double> map = list.stream().collect(Collectors.toMap(OrderCollectAmtVo::getDataDate, e -> e.getAmt().doubleValue()));
                        r.setDetails(DataConversionUtils.getCurDateMonthDataInit(req.getStartTime(),req.getEndTime(),map));
                    }
                }
                reportMasterDealerRes.setMasterDealerSales(reportDealerSalesDetailVos);
            }
        }

        return reportMasterDealerRes;

    }


}
